//
//  AnnotationView.m
//  Drawer
//
//  Created by Adam Cue on 1/18/11.
//  Copyright Adam Cue 2011.
//
//  This program is licensed and distributed under the terms of the GNU General Public License.  
//	The text for the license can be found in the license.txt file in this project.
//

#import "AnnotationView.h"
#import "DrawingInfo.h"

@interface AnnotationView (Private)
#pragma mark UserActions
- (void)erase:(NSSet *)touches withEvent:(UIEvent *)event;
@end

@implementation AnnotationView

@synthesize touchPoints = _touchPoints;
@synthesize currentPoints = _currentPoints;
@synthesize drawColor = _drawColor;
@synthesize delegate;
@synthesize drawWidth;
@synthesize shouldDraw;
@synthesize shouldErase;
@synthesize highlighting;
@synthesize page;


- (id)initWithFrame:(CGRect)frame {
    if(self = [super initWithFrame:frame]) {
		self.backgroundColor = [UIColor clearColor];
		_drawColor = [[UIColor alloc] initWithRed:0.9529 green:0.9529 blue:0.0824 alpha:0.5];
		drawWidth = 10.0;
		_touchPoints = [[NSMutableArray alloc] init];
    }
    return self;
}

- (void)dealloc {
   self.touchPoints = nil;
   self.currentPoints = nil;
   self.drawColor = nil;
   self.delegate = nil;
   
   [super dealloc];
}

- (void)drawRect:(CGRect)rect {
   if (self.touchPoints.count == 0)
      return;
   CGContextRef context = UIGraphicsGetCurrentContext();
   for(NSMutableArray *drawPoints in self.touchPoints){
      if(drawPoints.count == 0){
			[drawPoints release];
			continue;
		}
		DrawingInfo *firstDraw = [drawPoints objectAtIndex:0];
		CGPoint firstPoint = firstDraw.location;
		CGContextSetStrokeColor(context, CGColorGetComponents(firstDraw.color.CGColor));
		CGContextSetLineWidth(context, firstDraw.width);
		CGContextBeginPath(context);
		CGContextMoveToPoint(context, firstPoint.x, firstPoint.y);
		int i = 1;
		while(i < drawPoints.count){
			DrawingInfo *nextDraw = [drawPoints objectAtIndex:i];
			CGContextAddLineToPoint(context, nextDraw.location.x, nextDraw.location.y);
			i++;
		}
		CGContextDrawPath(context, kCGPathStroke);
	}
}

#pragma mark UserActions
- (void)erase:(NSSet *)touches withEvent:(UIEvent *)event{
	if([self.touchPoints count] == 0)
		return;
	UITouch *touch = [[event touchesForView:self] anyObject];
	CGPoint location = [touch locationInView:self];
	int eraseIx = 0;
	for(NSMutableArray *erasePoints in self.touchPoints){
		int ix = 0;
		for(DrawingInfo *point in erasePoints){
			if(point.location.x >= location.x - 4 && point.location.x <= location.x + 4 && point.location.y >= location.y - 10 && point.location.y <= location.y + 10){
				if(ix == 0 || ix == [erasePoints count] - 1){
					[erasePoints removeObjectAtIndex:ix];
					if([erasePoints count] <= 2){
						[self.touchPoints removeObjectAtIndex:eraseIx];
					}
					[self setNeedsDisplay];
					return;
				}
				else{
					NSRange range = NSMakeRange(ix, [erasePoints count] - ix);
					NSRange range2 = NSMakeRange(ix + 1, [erasePoints count] - 1 - ix);
					NSArray *temp = [erasePoints subarrayWithRange:range2];
					NSMutableArray *subArray = [NSMutableArray arrayWithArray:temp];
					[erasePoints removeObjectsInRange:range];
					[self.touchPoints addObject:subArray];
					if([erasePoints count] <= 2){
						[self.touchPoints removeObjectAtIndex:eraseIx];
					}
					[self setNeedsDisplay];
					return;
				}
			}
			ix++;
		}
		eraseIx++;
	}
}

#pragma mark UIResponder Methods
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
	if(shouldErase == YES){
		[self erase:touches withEvent:event];
		return;
	}	
	if(shouldDraw == YES){
		_currentPoints = [[NSMutableArray alloc] init];
		UITouch *touch = [[event touchesForView:self] anyObject];
		CGPoint location = [touch locationInView:self];
		DrawingInfo *point = [[DrawingInfo alloc] initWithLocation:location color:self.drawColor width:drawWidth];
		[self.currentPoints addObject:point];
		[self.touchPoints addObject:self.currentPoints];
		[point release];
	}
}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
	if(shouldErase == YES){
		[self erase:touches withEvent:event];
		return;
	}
	if(shouldDraw == YES){
		UITouch *touch = [[event touchesForView:self] anyObject];
		CGPoint location = [touch locationInView:self];
		DrawingInfo *point;
		if(highlighting){
			point = [[DrawingInfo alloc] initWithLocation:CGPointMake(location.x, [[self.currentPoints lastObject] location].y) color:self.drawColor width:drawWidth];
		}
		else{
			point = [[DrawingInfo alloc] initWithLocation:location color:self.drawColor width:drawWidth];
		}
		[self.currentPoints addObject:point];
		[point release];
		[self.touchPoints removeLastObject];
		[self.touchPoints addObject:self.currentPoints];
		[self setNeedsDisplay];
	}
}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
	if(shouldErase == YES){
		[delegate saveDrawing:self.touchPoints atPage:self.page];
		return;
	}
	if(shouldDraw == YES){
		UITouch *touch = [[event touchesForView:self] anyObject];
		CGPoint location = [touch locationInView:self];
		DrawingInfo *point;
		if(highlighting){
			point = [[DrawingInfo alloc] initWithLocation:CGPointMake(location.x, [[self.currentPoints lastObject] location].y) color:self.drawColor width:self.drawWidth];
		}
		else{
			point = [[DrawingInfo alloc] initWithLocation:location color:self.drawColor width:self.drawWidth];
		}
		[self.currentPoints addObject:point];
		[self.touchPoints removeLastObject];
		[self.touchPoints addObject:self.currentPoints];
		self.currentPoints = nil;
		[delegate saveDrawing:self.touchPoints atPage:self.page];
		[point release];
		[self setNeedsDisplay];
	}
}

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
   if(self.shouldDraw == NO && self.shouldErase == NO){
		return NO;
	}
	return [super pointInside:point withEvent:event];
}

#pragma mark External Methods
- (void)setDrawColor:(UIColor *)selectedDrawColor{
	self.drawColor = [[UIColor alloc] initWithRed:CGColorGetComponents(selectedDrawColor.CGColor)[0] green:CGColorGetComponents(selectedDrawColor.CGColor)[1]
                                            blue:CGColorGetComponents(selectedDrawColor.CGColor)[2] alpha:0.7];
}

-(void)clear {
	[self.touchPoints removeAllObjects];
	[self setNeedsDisplay];
	[delegate saveDrawing:self.touchPoints atPage:page];
}


@end
